#include "../inc/Circle.h"
#include "../inc/Tools.h"
#include <iostream>

using namespace std;


Circle::Circle (void)
{
	A = 0;
	B = 0;
	C = 0;
	R = 0;
}               

Circle::Circle(float _a, float _b, float _r)
{
	A = _a; 
	B = _b;
	C = 0;
	R = _r;
}

Circle::Circle(float _a, float _b, float _c, float _r)
{
	A = _a;
	B = _b;
	C = _c;
	R = _r;
}

Circle::Circle(CVertexO _p1, CVertexO _p2, CVertexO _p3)
{
	/* Cf graphics gems Book 1 page 21 */
	CVertexO p31, p21, p32, p12, p13, p23;
	float d1, d2, d3, c1, c2, c3, c;

	p31.P() = diffPoint( _p3, _p1 ).P();
	p21.P() = diffPoint( _p2, _p1 ).P();
	p32.P() = diffPoint( _p3, _p2 ).P();
	p12.P() = diffPoint( _p1, _p2 ).P();
	p13.P() = diffPoint( _p1, _p3 ).P();
	p23.P() = diffPoint( _p2, _p3 ).P();

	d1 = scalarProduct2D( p31, p21 );
	d2 = scalarProduct2D( p32, p12 );
	d3 = scalarProduct2D( p13, p23 );

	c1 = d2*d3;
	c2 = d3*d1;
	c3 = d1*d2;
	c = c1 + c2 + c3;

	R = 0.5*sqrt(((d1+d2)*(d2+d3)*(d3+d1))/c);
	A = (((c2 + c3)*_p1.P()[0]) + ((c3+c1)*_p2.P()[0]) + ((c1+c2)*_p3.P()[0]))/(2*c);
	B = (((c2 + c3)*_p1.P()[1]) + ((c3+c1)*_p2.P()[1]) + ((c1+c2)*_p3.P()[1]))/(2*c);
	C = 0;
}

Circle::Circle(const Circle & _c)
{
	this->A = _c.A;
	this->B = _c.B;
	this->C = _c.C;
	this->R = _c.R;
}

Circle::~Circle(){}

void Circle::setABR(float _a, float _b, float _r)
{
	this->A = _a;
	this->B = _b;
	this->C = 0;
	this->R = _r;
}

void Circle::setABCR(float _a, float _b, float _c, float _r)
{
	this->A = _a;
	this->B = _b;
	this->C = _c;
	this->R = _r;
}

void Circle::draw( float _z )
{
	int sections = 40; /* Nombre de sections utilises pour dessiner le cercle */
	float twoPi = 2.0f * 3.14159f;

	glColor3f(1,0,0);
	glBegin(GL_LINE_LOOP);
	for(int i = 0; i <= sections;i++) 
	{
		glVertex3f(this->getR() * cos(i *  twoPi / sections) + this->getA(), this->getR() * sin(i * twoPi / sections)  + this->getB(), _z );
	}
	glEnd();
	glColor3f(1,1,1);
}

void Circle::draw(float _z, float _r, float _g, float _b)
{
	int sections = 40; /* Nombre de sections utilises pour dessiner le cercle */
	float twoPi = 2.0f * 3.14159f;

	glColor3f(_r,_g,_b);
	glBegin(GL_LINE_LOOP);
	for(int i = 0; i <= sections;i++) 
	{
		glVertex3f(this->getR() * cos(i *  twoPi / sections) + this->getA(), this->getR() * sin(i * twoPi / sections)  + this->getB(), _z );
	}
	glEnd();
	glColor3f(1,1,1);
}

void Circle::print()
{
	cout<<"Cercle de centre ( "<<A<<", "<<B<<", "<<C<<" ) et de rayon "<<R<<endl;
}

bool Circle::intersect(Circle _c)
{
	float dist = this->getR() + _c.getR();
	return (sqrt(pow(this->getA()-_c.getA(), 2) + pow(this->getB()-_c.getB(), 2)) < dist);
}

int Circle::conflict(Circle _c)
{
	float dist = sqrt(pow(this->getA()-_c.getA(), 2) + pow(this->getB()-_c.getB(), 2));
	float sum = this->getR() + _c.getR();

	if ( dist < sum )
	{
		if ( dist + _c.getR() < this->getR() || dist + this->getR() < _c.getR() )
		return 0;

		return 1;
	}

	return -1;
}

